package org.wejob.core.log.util;


public class Timer {
    private final Time time;
    private long startMs;
    private long currentTimeMs;
    private long deadlineMs;

    Timer(Time time, long timeoutMs) {
        this.time = time;
        this.update();
        this.reset(timeoutMs);
    }

    public boolean isExpired() {
        return this.currentTimeMs >= this.deadlineMs;
    }

    public boolean notExpired() {
        return !this.isExpired();
    }

    public void updateAndReset(long timeoutMs) {
        this.update();
        this.reset(timeoutMs);
    }

    public void reset(long timeoutMs) {
        if (timeoutMs < 0L) {
            throw new IllegalArgumentException("Invalid negative timeout " + timeoutMs);
        } else {
            this.startMs = this.currentTimeMs;
            if (this.currentTimeMs > Long.MAX_VALUE - timeoutMs) {
                this.deadlineMs = Long.MAX_VALUE;
            } else {
                this.deadlineMs = this.currentTimeMs + timeoutMs;
            }

        }
    }

    public void update() {
        this.update(this.time.milliseconds());
    }

    public void update(long currentTimeMs) {
        this.currentTimeMs = Math.max(currentTimeMs, this.currentTimeMs);
    }

    public long remainingMs() {
        return Math.max(0L, this.deadlineMs - this.currentTimeMs);
    }

    public long currentTimeMs() {
        return this.currentTimeMs;
    }

    public long elapsedMs() {
        return this.currentTimeMs - this.startMs;
    }

    public void sleep(long durationMs) {
        long sleepDurationMs = Math.min(durationMs, this.remainingMs());
        this.time.sleep(sleepDurationMs);
        this.update();
    }
}
